package de.tum.in.msspp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.http.util.ByteArrayBuffer;

import de.tum.in.bluetooth.BluetoothClientP2P;
import de.tum.in.bluetooth.IBluetoothManager;
import de.tum.in.bluetooth.gui.BluetoothService;
import de.tum.in.msspp.graph.Graph;
import de.tum.in.msspp.graph.GraphException;
import de.tum.in.msspp.message.Mailbox;
import de.tum.in.msspp.services.ServiceProvider;
import android.app.Activity;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;
import android.widget.ImageView;
import android.widget.Toast;

public class GraphView extends Activity implements IBluetoothManager{

	// Intent Codes
	private static final int REQUEST_TRADE = 1;

	Graph graph;
	ImageView imageView;
	
	ServiceProvider service;
	BluetoothClientP2P client;

	// Handles the streamed XML that is sent via Bluetooth
	Handler mGraphHandler;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.graph);

		imageView = (ImageView) findViewById(R.id.ImageView);
		
		String photographer = (String) getIntent().getExtras().get("user");

		//Load Graph
		graph = new Graph(photographer + "_graph");
		graph.load(getApplicationContext());

		//Setup service
		service = new ServiceProvider(null, this.getApplicationContext());

		Bitmap graphImage = service.sendGraph(graph.toXML());
		if(graphImage != null)
			imageView.setImageBitmap(graphImage);
		
		
		
		//Set Image
		//TODO take cached graph image

		mGraphHandler = new Handler()
		{	
			final static int SHOULD_TRADE_GRAPH = 1;
			final static int WANTS_TRADE_GRAPH = 2;
			
			boolean tradedMyGraph = false;
			/**
			 * exchange the graphs and close BT-Connection when successfully sent
			 */
			@Override
			public void handleMessage(Message m) 
			{
				
				switch (m.what) 
				{
					case SHOULD_TRADE_GRAPH: 
					{
						//Somebody wants to trade graphs
						
						if(m.obj.toString().equals("<ENDE>"))
						{
							Log.i("FaceCruller", "Received <Ende> tag, now disconnecting");
							
							client.disconnect();
						}else{
							//So try to receive Graph
							Log.i("FaceCruller", "Received data, try to parse graph");
							
							String graphXML = m.obj.toString();
							Graph receivedGraph = new Graph("receivedGraph",graphXML);
							
							Log.i("FaceCruller", "Graph sueccessfully parsed");
						
							if(!tradedMyGraph)
							{
								//Send my Graph
								Log.i("FaceCruller", "Try to send my graph");
								
								client.sendObject(graph.toXML());
								tradedMyGraph=true;
								
								Log.i("FaceCruller", "Graph successfully sent");
							}else{
								Log.i("FaceCruller", "I think trade is done");
								client.sendObject("<ENDE>");
								Log.i("FaceCruller", "Sent <ENDE> tag");
							}
							
							Log.i("FaceCruller", "Try to merge traded graphs");
							
							try 
							{
								graph.merge(receivedGraph);
								graph.save(getApplicationContext());
								
								Log.i("FaceCruller", "Try to update merged graph image");
								
								Bitmap graphImage = service.sendGraph(graph.toXML());
								if(graphImage != null)
									imageView.setImageBitmap(graphImage);
								
								Log.i("FaceCruller", "Graph successfully updated");
								
								Toast.makeText(getApplicationContext(), "Graph successfully traded, yeah", Toast.LENGTH_LONG).show();
							} catch (GraphException e) 
							{
								Toast.makeText(getApplicationContext(), "Trading your graph failed, sorry", Toast.LENGTH_LONG).show();
								e.printStackTrace();
							}
						}
					}
					break;
					case WANTS_TRADE_GRAPH:
					{
						Log.i("FaceCruller", "Try to send my graph");
						
						//I wanna trade my graph
						client.sendObject(graph.toXML());
						tradedMyGraph = true;
						
						Log.i("FaceCruller", "Graph successfully sent");
					}
				}
			}
		};
		
		//Start bluetooth client
		client = new BluetoothClientP2P(mGraphHandler, "GraphService");
		client.setBluetoothDatahandler(this);
		client.start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.graphmenu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) 
	{
		switch (item.getItemId()) 
		{
			case R.id.menu_connect_send: 
			{
				Intent intent = new Intent(this, BluetoothService.class);
				// intent.putExtra("graph", mStrGraph);
				startActivityForResult(intent, REQUEST_TRADE);
			}
			break;
			case R.id.menu_mailbox: 
			{
				Intent intent = new Intent(this, Mailbox.class);
				intent.putExtra("graph", this.graph.getName());
				startActivity(intent);
			}
			break;
		}

		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) 
	{
		super.onActivityResult(requestCode, resultCode, data);
		
		if (requestCode == REQUEST_TRADE) 
		{
			//Connect to other device
			if (resultCode == RESULT_OK) 
			{
				BluetoothDevice partner = (BluetoothDevice) data.getExtras().get("device");
				client.connectToDevice(partner);
			}
		}
	}

	@Override
	public Object receiveObject(InputStream input) throws IOException
	{	
		String data = null;
		
		ByteArrayBuffer buffer = new ByteArrayBuffer(1024);
		
		int receivedByte;
		while((receivedByte = input.read()) > 0)
		{
			buffer.append(receivedByte);
		}
		
		data = new String(buffer.toByteArray());
		
		return data;
	}

	@Override
	public void sendObject(OutputStream output, Object data)  throws IOException
	{
		//Send Graph
		client.sendString((String)data);
		//Send 0-Bit
		client.sendByte(0);
	}
}
